package com.levi.juc.forkjoin;

import com.levi.pojo.User;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;

public class Test01 {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
//        test1();//普通方式求和计算用时4423 ms
//        test2(0L,10_0000_0000L);//forkjoin方法 计算用时 4000 ms
        test3(0L,10_0000_0000L); //计算用时 283 ms  效率提高了几十倍
    }

    /**
     * 原始的求和方法
     */
    public static void test1() {
        long start = System.currentTimeMillis();
        Long sum = 0L;
        for (int i = 1; i <= 10_0000_0000L; i++) {
            sum += i;
        }
        long end = System.currentTimeMillis();
        long use = end - start;
        System.out.println("计算用时:" +use+ "sum= "+sum);
    }

    /**
     * 用  forkjoin   拆分合并方式计算
     * @param start
     * @param end
     */
    public static void test2(Long start,Long end) throws ExecutionException, InterruptedException {
        long startTime = System.currentTimeMillis();
        ForkJoinPool forkJoinPool = new ForkJoinPool();

        ForkJoinTest task = new ForkJoinTest(start, end);
        //submit是异步提交任务有返回值   executor是同步执行任务，没有返回值
        ForkJoinTask<Long> submit = forkJoinPool.submit(task);
        Long sum = submit.get();
        long endTime = System.currentTimeMillis();
        long useTime =endTime - startTime;
        System.out.println("计算用时:" + useTime + "sum= "+sum);
    }

    /**
     * 用 stream并行流  计算的方法
     * @param start
     * @param end
     */
    public static void test3(Long start,Long end) {
        long startTime = System.currentTimeMillis();
        //parallel()方法时并行计算
        long sum = LongStream.rangeClosed(start, end).parallel().sum();
        long endTime = System.currentTimeMillis();
        System.out.println("计算用时:" + (endTime - startTime) + "sum= "+sum);
    }

    }

